package com.raler.proyar.bl.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.raler.proyar.bl.exception.GeneralBusinessException;
import com.raler.proyar.bl.interfaces.GeneralBS;
import com.raler.proyar.il.exception.GeneralDAOException;
import com.raler.proyar.il.interfaces.GeneralDAO;
import com.raler.proyar.il.model.GeneralDomainObject;
import com.raler.proyar.pl.dto.AbstractDto;

public abstract class GeneralBSImpl<E extends GeneralDomainObject> implements GeneralBS<E> {

	protected abstract GeneralDAO<E> getDAO();

	@Override
	public E insert( E entity ) throws GeneralBusinessException {
		try {
			getDAO().insert( entity );

			return entity;
		} catch( GeneralDAOException e ) {
			throw new GeneralBusinessException( e );
		}
	}

	@Override
	public E update( E entity ) throws GeneralBusinessException {
		try {
			return getDAO().update( entity );
		} catch( GeneralDAOException e ) {
			throw new GeneralBusinessException( e );
		}
	}

	@Override
	public <T extends AbstractDto> E update( T dto, Function<T, E> conversor ) throws GeneralBusinessException {
		if( dto != null && dto.getId() != null && conversor != null ) {
			try {
				E entity = conversor.apply( dto );
				return getDAO().update( entity );
			} catch( GeneralDAOException e ) {
				throw new GeneralBusinessException( e );
			}
		}
		return null;
	}

	@Override
	public <T extends AbstractDto> List<E> update( List<T> dtos, Function<T, E> conversor ) throws GeneralBusinessException {
		if( dtos != null && !dtos.isEmpty() && conversor != null ) {
			try {
				List<E> entities = Lists.transform( dtos, conversor );
				return getDAO().update( entities );
			} catch( GeneralDAOException e ) {
				throw new GeneralBusinessException( e );
			}
		}
		return null;
	}

	@Override
	public void remove( Serializable id ) throws GeneralBusinessException {
		if( id != null ) {
			try {
				E entity = getDAO().findById( id );
				if( entity != null ) {
					getDAO().remove( entity );
				}
			} catch( GeneralDAOException e ) {
				throw new GeneralBusinessException( e );
			}
		}
	}

	@Override
	public E findById( Serializable id ) throws GeneralBusinessException {
		try {
			return getDAO().findById( id );
		} catch( GeneralDAOException e ) {
			throw new GeneralBusinessException( e );
		}
	}

	@Override
	public List<E> findAll() throws GeneralBusinessException {
		List<E> entities = new ArrayList<E>();
		try {
			entities = getDAO().findAll();
		} catch( GeneralDAOException e ) {
			throw new GeneralBusinessException( e );
		}
		return entities;
	}

}
